package org.example.pingpong.common.exception;

import org.example.pingpong.domain.vo.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;

/**
 * 全局异常处理类，用于捕获并处理应用程序中的各种异常，统一返回格式的错误信息。
 * 该类主要用于处理以下异常：
 * 1. ConstraintViolationException：数据验证失败异常
 * 2. MethodArgumentNotValidException：方法参数校验失败异常
 * 3. ForbiddenException：自定义的禁止访问异常
 */
@RestControllerAdvice
public class ForbiddenExceptionHandler {
    // 日志记录器，用于记录异常信息
    private static final Logger log = LoggerFactory.getLogger(ForbiddenExceptionHandler.class);

    /**
     * 处理 ConstraintViolationException 异常，通常用于处理数据验证失败的情况。
     * 根据异常消息判断是哪一类验证失败，返回对应的错误信息。
     *
     * @param e ConstraintViolationException 异常对象
     * @return 返回一个标准的错误结果，包含错误代码和描述信息
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result exceptionHandler(ConstraintViolationException e) {
        // 针对用户名或密码不符合格式的特殊处理
        if (e.getMessage().contains("login.username: 需要匹配正则表达式"))
            return Result.error(541, "用户名或密码不符合格式规范");
        else if (e.getMessage().contains("login.pwd: 需要匹配正则表达式\"^\\S{5,16}$\""))
            return Result.error(542, "用户名或密码不符合格式规范");

        // 如果是其他验证失败的情况，记录异常信息并返回通用错误
        log.error(e.getMessage());
        return Result.error(e.getMessage());
    }

    /**
     * 处理 MethodArgumentNotValidException 异常，通常用于处理 Spring 表单或请求体参数验证失败的情况。
     * 根据字段错误信息返回具体的错误提示。
     *
     * @param e MethodArgumentNotValidException 异常对象
     * @return 返回一个标准的错误结果，包含错误代码和描述信息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result exceptionHandler(MethodArgumentNotValidException e) {
        // 针对邮箱和用户名格式错误的特殊处理
        if (e.getMessage().contains("Field error in object 'user' on field 'email'"))
            return Result.error(543, "邮箱不符合格式规范");
        else if (e.getMessage().contains("Field error in object 'user' on field 'nickname'"))
            return Result.error(544, "用户名不符合格式规范");

        // 如果是其他字段错误，记录异常信息并返回通用错误
        log.error(e.getMessage());
        return Result.error(e.getMessage());
    }

    /**
     * 处理 ForbiddenException 异常，该异常通常用于表示用户没有权限执行某个操作。
     * 该方法记录错误信息并返回包含错误描述的失败响应。
     *
     * @param ex ForbiddenException 异常对象
     * @return 返回一个失败响应，包含错误消息
     */
    @ExceptionHandler(ForbiddenException.class)
    public Result userExcetionHandler(ForbiddenException ex) {
        log.error("Forbidden exception: " + ex.getMessage());  // 记录详细的错误信息
        return Result.fail(ex.getMessage());  // 返回失败响应，包含错误消息
    }

    /**
     * 捕获其他异常（当前已注释掉）
     * 通用的异常捕获处理，适用于没有特别处理的其他异常情况。
     *
     * @param ex Exception 异常对象
     * @return 返回一个标准的错误结果，提示系统异常
     */
    // @ExceptionHandler(Exception.class)
    // public Result serviceExceptionHandler(Exception ex) {
    //     log.error("Exception occurred: " + ex.getMessage());
    //     return Result.fail("系统异常，请稍后再试");  // 返回通用错误提示
    // }
}
